//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <winhack.h>
#include <ddk.h>
#include <stdio.h>
#include "CDeviceEventManager.h"

ELAPI _CSystem_RegisterRunningObject(
    _ELASTOS WString name,
    PInterface pService);

ELAPI _CSystem_UnregisterRunningObject(
    _ELASTOS WString name);

IDeviceEventHandler *g_pDeviceEventHandler = NULL;
static IDeviceEventManager *s_pDeviceEventManager = NULL;

class CEventManDev : public CDeviceDriver {
public:
    CARAPI Read(
        /* [in] */ Int64 u64Offset,
        /* [in] */ Int32 bytesToRead,
        /* [out] */ MemoryBuf * pBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Write(
        /* [in] */ Int64 u64Offset,
        /* [in] */ const MemoryBuf & buffer,
        /* [out] */ Int32 * pBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent);

   CARAPI Control(
        /* [in] */ Handle32 nControlCode,
        /* [in] */ const MemoryBuf & inBuffer,
        /* [out] */ MemoryBuf * pOutBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    virtual void Dispose();
};

EXTERN IDeviceDriver * CDECL RegisterEventManager(uint_t uDeviceNo, void *pvParameter)
{
    CEventManDev *pStatServer = new CEventManDev;
    if (NULL == pStatServer) {
        return NULL;
    }
    pStatServer->AddRef();

    CDeviceEventManager *pem = new CDeviceEventManager();
    if (NULL == pem) {
        delete pStatServer;
        return NULL;
    }
    ECode ec = pem->Initialize();
    if (FAILED(ec)) {
        delete pStatServer;
        return NULL;
    }
    g_pDeviceEventHandler = (IDeviceEventHandler *)pem;
    g_pDeviceEventHandler->AddRef();

    ec = _CSystem_RegisterRunningObject(L"DeviceEventManager", g_pDeviceEventHandler);
    if (FAILED(ec)) {
        delete pStatServer;
        g_pDeviceEventHandler->Release();
        kprintf("Register DeviceEventManager failed, ec = 0x%08x\n", ec);
        return NULL;
    }

    s_pDeviceEventManager = (IDeviceEventManager *)pem;
    s_pDeviceEventManager->AddRef();

    return pStatServer;
}

EXTERN void DisposeEventManager(IDeviceDriver *pStatServer)
{
    if(pStatServer != NULL) {
        ((CEventManDev *)pStatServer)->Dispose();
    }
}

ECode CEventManDev::Read(
        /* [in] */ Int64 u64Offset,
        /* [in] */ Int32 bytesToRead,
        /* [out] */ MemoryBuf * pBuffer,
        /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode CEventManDev::Write(
        /* [in] */ Int64 u64Offset,
        /* [in] */ const MemoryBuf & buffer,
        /* [out] */ Int32 * pBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode CEventManDev::Control(
        /* [in] */ Handle32 nControlCode,
        /* [in] */ const MemoryBuf & inBuffer,
        /* [out] */ MemoryBuf * pOutBuffer,
        /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

void CEventManDev::Dispose()
{
    if (g_pDeviceEventHandler) g_pDeviceEventHandler->Release();
    if (s_pDeviceEventManager) s_pDeviceEventManager->Release();
    ECode ec = _CSystem_UnregisterRunningObject(L"DeviceEventManager");
    if (FAILED(ec)) {
        kprintf("Failed to unregister DeviceEventManager service!\n");
    }

    delete this;
}


EXTERN ECode EmSendEvent(
    /* [in] */ UInt32 uEventNum,
    /* [in] */ const MemoryBuf & ebEventData)
{
    return s_pDeviceEventManager->SendEvent(uEventNum, ebEventData);
}

EXTERN ECode EmPostEvent(
    /* [in] */ UInt32 uEventNum,
    /* [in] */ const MemoryBuf & ebEventData)
{
    return s_pDeviceEventManager->PostEvent(uEventNum, ebEventData);
}

